home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 9 / Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO / 015a / combi113.zip / COMBI.C < prev    next >
C/C++ Source or Header  |  1993-05-03  |  12KB  |  390 lines

  1. /*
  2.  *  This program is copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.
  3.  *
  4.  * The source is supplied as an example of interface to COMBI-disk (C)
  5.  * device driver. You may change the source as You wish, however I'm not
  6.  * responsible for the results of Your changes.
  7.  *
  8.  * Exit status:
  9.  *            3 - COMBI-disk not found;
  10.  *            2 - incorrect usage;
  11.  *            1 - can't change options or reallocate buffer;
  12.  *            0 - O'K - no errors.
  13.  *
  14.  * The program is written for MS C 6.0 and may be compiled in TINY or
  15.  * SMALL memory model.
  16.  *
  17.  * I apologize if the code looks cumbersome but I tried to make it most
  18.  * compatible with other compilers. (Turbo C 2.0 compiles it O'K).
  19.  *
  20.  */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <dos.h>
  27. #include <ctype.h>
  28. #include "ioctl.h"    /* definitions of structures and control codes */
  29.  
  30. /* ANSI escape sequences to control colour output. If ANSI is not detected
  31.  * all they are changed to point to an empty string. */
  32.  
  33. char *A_bold = "\x1b[1m";
  34. char *A_red  = "\x1b[1;31m";
  35. char *A_yell = "\x1b[1;33m";
  36. char *A_cyan = "\x1b[1;36m";
  37. char *A_norm = "\x1b[0m";
  38.  
  39. char   drive=2;
  40.  
  41. static void
  42. show_status(struct combi_status *cmb_st)
  43. {
  44.   char  opt;
  45.  
  46.   printf("\t%sCOMBI-disk version %1d.%02d installed as drive %c:%s\n",
  47.           A_yell,
  48.           cmb_st->version >> 8, cmb_st->version & 0xff, drive+'A'-1, A_norm);
  49.  
  50.   printf("\n\t%sCurrent status:%s\n", A_bold, A_norm);
  51.  
  52.   printf("buffer size:  %s%5dK%s\n", A_cyan, cmb_st -> buff_size, A_norm);
  53.  
  54.   printf("current size: %s%5dK%s\n", A_cyan, cmb_st -> curr_size, A_norm);
  55.  
  56.   printf("total number of blocks:   %s%4d%s (%s%d%s sectors each)\n",
  57.          A_cyan, cmb_st -> n_blocks, A_norm,
  58.          A_cyan, cmb_st -> bl_sect, A_norm);
  59.  
  60.   printf("current number of blocks: %s%4d%s (%s%d%s - RAM disk, %s%d%s - cache)\n",
  61.          A_cyan, cmb_st -> n_curr, A_norm,
  62.          A_cyan, cmb_st -> n_bl_RD, A_norm,
  63.          A_cyan, cmb_st -> n_bl_Cache, A_norm);
  64.  
  65.   opt = cmb_st -> COMBI_options;
  66.   if(opt & OPT_WR_ON) {       /* only if write caching is on */
  67.     printf("dirty blocks: %s%d%s, errors: %s%d%s\n",
  68.             A_cyan, cmb_st ->  n_dirty, A_norm,
  69.             A_cyan, cmb_st -> n_errors, A_norm);
  70.   };
  71.  
  72.   printf("\n\t%sOptions in order:%s\n", A_bold, A_norm);
  73.  
  74.   if(!(opt & OPT_OFF)) {
  75.     printf("cache is %son%s (%s),\n", A_cyan, A_norm,
  76.            (opt & OPT_FREEZE) ? "frozen" : "not frozen");
  77.   printf("write caching is %s%s%s,\n", A_cyan,
  78.            (opt & OPT_WR_ON)  ? "on"     : "off", A_norm);
  79.   if(opt & OPT_WR_ON) {
  80.     printf("delayed write is %s%s%s,\n", A_cyan,
  81.            (opt & OPT_DW_OFF) ? "off"    : "on",  A_norm);
  82.   };
  83.   } else {
  84.   printf("cache is %soff%s,\n", A_cyan, A_norm);
  85.   };
  86.   printf("memory allocation is %s%s%s.\n", A_cyan,
  87.          (opt & OPT_MEM)    ? "fixed"  : "not fixed", A_norm);
  88.  
  89.   printf("\n\t%sStatistics:%s\n", A_bold, A_norm);
  90.  
  91.   printf("RAM disk reads: %s% 6u/%-6u%s\n",
  92.           A_cyan, cmb_st -> read_RD_num, cmb_st -> read_RD_sect, A_norm);
  93.  
  94.   printf("RAM disk writes:%s% 6u/%-6u%s\n", A_cyan,
  95.           cmb_st -> write_RD_num, cmb_st -> write_RD_sect, A_norm);
  96.  
  97.   if(!(opt & OPT_OFF)){
  98.     printf("Hard disk reads - requested: %s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
  99.             A_cyan, cmb_st -> read_rq,    cmb_st -> read_sect, A_norm,
  100.             A_cyan, cmb_st -> read_rq_a,  cmb_st -> read_sect_a, A_norm);
  101.     printf("Hard disk writes - requested:%s% 6u/%-6u%s, passed to BIOS:%s% 6u/%-6u%s\n",
  102.             A_cyan, cmb_st -> write_rq,   cmb_st -> write_sect, A_norm,
  103.             A_cyan, cmb_st -> write_rq_a, cmb_st -> write_sect_a, A_norm);
  104.   }
  105. }
  106.  
  107. static int
  108. change_mem(char drive, int ver, int memch)
  109. {
  110.   unsigned char ctl[12];
  111.   union REGS r;
  112.   *(int *)&ctl = ver;
  113.   if(memch > 0) {
  114.     ctl[2] = CMD_EXPAND;    /* command code for COMBI-disk - expand memory */
  115.     *(int *)&ctl[3] = memch;/* the amount of Kbytes to change memory size  */
  116.   } else {
  117.     ctl[2] = CMD_SHRINK;    /* command code for COMBI-disk - shrink memory */
  118.     *(int *)&ctl[3] = - memch;
  119.   }
  120.  
  121.   r.x.ax=0x4405;    /* DOS function: 'write IOCtl to block device' */
  122.   r.h.bl=drive;     /* device number  */
  123.   r.x.dx=(unsigned)&ctl;  /* address of IOCtl packet */
  124.   r.x.cx=5;         /* IOCtl packet length  */
  125.   intdos(&r,&r);
  126.   if(r.x.cflag & 01)      /* test for error return code */
  127.       return -1;
  128.   else
  129.       return 0;
  130. }
  131.  
  132. static int
  133. change_opt(char drive, int ver, char opt)
  134. {
  135.   unsigned char ctl[12];
  136.   union REGS r;
  137.   *(int *)&ctl = ver;
  138.   ctl[2] = CMD_CH_OPT;    /* command to COMBI-disk - change options */
  139.   ctl[3] = opt;           /* the byte with new options follows the command */
  140.  
  141.   r.x.ax=0x4405;
  142.   r.h.bl=drive;
  143.   r.x.dx=(unsigned)&ctl;
  144.   r.x.cx=4;
  145.   intdos(&r,&r);
  146.   if(r.x.cflag & 01)
  147.       return -1;
  148.   else
  149.       return 0;
  150. }
  151.  
  152. static int
  153. reset_counters(char drive, int ver)
  154. {
  155.   unsigned char ctl[12];
  156.   union REGS r;
  157.   *(int *)&ctl = ver;
  158.   ctl[2] = CMD_RESET_C;   /* command to COMBI-disk - reset counters */
  159.   ctl[3] = 7;             /* reset all three types of counters */
  160.  
  161.   r.x.ax=0x4405;
  162.   r.h.bl=drive;
  163.   r.x.dx=(unsigned)&ctl;
  164.   r.x.cx=4;
  165.   intdos(&r,&r);
  166.   if(r.x.cflag & 01)
  167.       return -1;
  168.   else
  169.       return 0;
  170. }
  171.  
  172. static void
  173. usage(void)
  174. {
  175.   printf("\t%sCOMBI-disk (C) control program.%s\n"
  176.          "Copyright 1992-1993 by Vadim V. Vlasov, Moscow, Russia.\n",
  177.          A_yell, A_norm);
  178.  
  179.   printf("Usage: %sCOMBI [[+|-]#] [<option>[+|-]]...%s\n",
  180.          "where:\n", A_bold, A_norm);
  181.   printf("    %s# (number)%s - expand or shrink memory used by COMBI-disk,\n",
  182.          A_bold, A_norm);
  183.   printf("    %sn%s - don't return 'sector not found' error,\n",
  184.          A_bold, A_norm);
  185.   printf("    %so%s - turn cache on ('%so-%s' - turn off),\n",
  186.          A_bold, A_norm, A_bold, A_norm);
  187.   printf("    %sb%s - turn write caching on ('%sb-%s' - off),\n",
  188.          A_bold, A_norm, A_bold, A_norm);
  189.   printf("    %si%s - start writing immediately ('%si-%s' - delayed writing),\n",
  190.          A_bold, A_norm, A_bold, A_norm);
  191.   printf("    %sf%s - fix memory settings ('%sf-%s' - release),\n",
  192.          A_bold, A_norm, A_bold, A_norm);
  193.   printf("    %sz%s - freeze cache ('%sz-%s' - un-freese),\n",
  194.          A_bold, A_norm, A_bold, A_norm);
  195.   printf("    %sr%s - reset all counters.\n",
  196.          A_bold, A_norm);
  197.   exit(2);
  198. }
  199.  
  200. static void
  201. chk_ansi(void)
  202. {
  203.   union REGS r;
  204.   r.x.ax = 0x4400;  /* DOS IOCtl - get handle info */
  205.   r.x.bx = 0x0001;  /* stdout handle */
  206.   intdos(&r,&r);
  207.  
  208.   if((r.x.dx & 0x82) == 0x82) {
  209.     r.x.ax = 0x1a00;
  210.     int86(0x2f, &r, &r);
  211.     if(r.h.al == 0xff)
  212.       return;
  213.   }
  214.  
  215.   /* Else output is redirected into file or ANSI is not installed.
  216.    * So, we should turn off escape sequences. */
  217.  
  218.   A_bold = A_yell = A_red = A_cyan = A_norm = "";
  219. }
  220.  
  221.  
  222. main(int argc, char *argv[])
  223. {
  224.   struct combi_status cmb_st;
  225.   union  REGS  r;
  226.   int i,j;
  227.   int exitstat=0;
  228.   char   *chpt, optchar;
  229.   char   oldopt, opt;
  230.  
  231.   chk_ansi(); /* Determine whether ANSI driver is installed and whether
  232.                * the output is redirected to file */
  233. /*
  234.  * Scan all drives and try to read IOCtl packet of length sizeof(cmb_st).
  235.  * If successful then probably that drive is COMBI's RAM disk. To ensure
  236.  * this we check that first 6 bytes of returned packet are "COMBI\0".
  237.  */
  238.  
  239.   do {
  240.     drive++;
  241.     r.x.ax=0x4404;
  242.     r.h.bl=drive;
  243.     r.x.cx=sizeof(cmb_st);
  244.     r.x.dx=(unsigned)&cmb_st;
  245.   } while (((intdos(&r,&r)!=sizeof(cmb_st))||
  246.            (r.x.cflag & 0x1)||
  247.            strcmp(cmb_st.ID_name,"COMBI"))&&(drive < 16));
  248.  
  249.   if(drive >= 16) {
  250.     printf("%sError: COMBI-disk not installed!(?)%s\n", A_red, A_norm);
  251.     exit(3);
  252.   }
  253.  
  254.   if(argc > 1) {    /* any parameters?  */
  255.     optchar = '\0';
  256.     oldopt = opt = cmb_st.COMBI_options;
  257.  
  258.     for(i=1; i < argc; i++) {   /* Scan all command line arguments. */
  259.  
  260.       strlwr(argv[i]);
  261.       if(isdigit(*argv[i]) || *argv[i]=='-' || *argv[i]=='+') {
  262.  
  263.         /* If an argument is a number then try to reallocate COMBI's
  264.          * memory size.*/
  265.  
  266.         j = atoi(argv[i]);
  267.         if(change_mem(drive, cmb_st.version, j)) {
  268.           printf("%sCan't reallocate memory!%s\a\n", A_red, A_norm);
  269.           exitstat = 1;
  270.         } else
  271.           printf("Memory reallocated by %+dK. ", j);
  272.       } else {
  273.         optchar = *argv[i];
  274.         chpt = argv[i]+1;
  275.         while(optchar) {
  276.           switch(optchar) {
  277.             case 'n':
  278.             /* Option 'n' - ignore (or not ignore if 'n-')
  279.              * 'sector not found error'. */
  280.               if(*chpt == '-') {
  281.                 opt &= ~OPT_NO_SNF;   /* Reset the option bit */
  282.                 chpt++;
  283.               } else {
  284.                 opt |= OPT_NO_SNF;    /* Set the option bit   */
  285.                 if(*chpt == '+')
  286.                     chpt++;
  287.               }
  288.               optchar = *chpt++;
  289.               break;
  290.             case 'o':
  291.             /* Option 'o' - turn cache on.  */
  292.               if(*chpt == '-') {
  293.                 opt |= OPT_OFF;
  294.                 chpt++;
  295.               } else {
  296.                 opt &= ~OPT_OFF;
  297.                 if(*chpt == '+')
  298.                     chpt++;
  299.               }
  300.               optchar = *chpt++;
  301.               break;
  302.             case 'b':
  303.             /* Option 'b' - turn background writing
  304.              * (== write caching) on.  */
  305.               if(*chpt == '-') {
  306.                 opt &= ~OPT_WR_ON;
  307.                 chpt++;
  308.               } else {
  309.                 opt |= OPT_WR_ON;
  310.                 if(*chpt == '+')
  311.                     chpt++;
  312.               }
  313.               optchar = *chpt++;
  314.               break;
  315.             case 'i':
  316.             /* Option 'i' - write immediately
  317.              * (or enable delayed writing if 'i-') in effect only if
  318.              * write caching (background writing) is on.  */
  319.               if(*chpt == '-') {
  320.                 opt &= ~OPT_DW_OFF;
  321.                 chpt++;
  322.               } else {
  323.                 opt |= OPT_DW_OFF;
  324.                 if(*chpt == '+')
  325.                     chpt++;
  326.               }
  327.               optchar = *chpt++;
  328.               break;
  329.             case 'z':
  330.             /* Option 'z' - freeze cache - no new sectors are read into
  331.              * cache after freezing and only that are in cache may be written
  332.              * in background.   */
  333.               if(*chpt == '-') {
  334.                 opt &= ~OPT_FREEZE;
  335.                 chpt++;
  336.               } else {
  337.                 opt |= OPT_FREEZE;
  338.                 if(*chpt == '+')
  339.                     chpt++;
  340.               }
  341.               optchar = *chpt++;
  342.               break;
  343.             case 'f':
  344.             /* Option 'z' - fix memory setting - disables automatic reallocation
  345.              * of XMS memory when it is requested by other programs.  */
  346.               if(*chpt == '-') {
  347.                 opt &= ~OPT_MEM;
  348.                 chpt++;
  349.               } else {
  350.                 opt |= OPT_MEM;
  351.                 if(*chpt == '+')
  352.                     chpt++;
  353.               }
  354.               optchar = *chpt;
  355.               break;
  356.             case 'r':
  357.             /* reset all counters */
  358.               if(reset_counters(drive, cmb_st.version)) {
  359.                   printf("%sCan't reset counters!%s\a\n", A_red, A_norm);
  360.                   exitstat = 1;
  361.               } else
  362.                   printf("Counters reset. ");
  363.               optchar = *chpt++;
  364.               break;
  365.             default:
  366.               printf("%sInvalid option: %s'%c'%s\n", A_red, A_bold,
  367.                      optchar, A_norm);
  368.             case '?':
  369.               usage();
  370.           }
  371.         }
  372.       }
  373.     }
  374.     if(oldopt != opt) {
  375.       if(change_opt(drive, cmb_st.version, opt)) {
  376.         printf("%sCan't change options!%s\a\n", A_red, A_norm);
  377.         exitstat = 1;
  378.       } else
  379.         printf("Options changed.");
  380.     } else
  381.         printf("Options unchanged.");
  382.     printf("\n");
  383.   } else {                  /* no arguments */
  384.     show_status(&cmb_st);   /* Show status returned by COMBI. */
  385.   }
  386.  
  387.   return exitstat;
  388. }
  389.  
  390.